#include "Util.h"

string toLower(string str) {
    string res = str;
    for (int i = 0; i < str.length(); i++) {
        res[i] = (char) tolower(str[i]);
    }
    return res;
}

bool isAllLetter(string str) {
    // traverse all characters
    for (int i = 0; i < str.length(); i++) {
        //return false if meet non characters
        if (!isalpha(str[i])) {
            return false;
        }
    }
    return true;
}

void printToken(const string &token, int code, int lineNum) {
    FILE *fp = freopen(lexResultTxt, "a", stdout); // append if exists
    string res;

    /********output format*******/
    /*int <KW,1>*/
    res += token; // append
    res += '\t';
    res += "<";
    //cout << res;

    switch (code) {
        /*case KW*/
        case Token::KW_INT:
        case Token::KW_VOID:
        case Token::KW_RETURN:
        case Token::KW_CONST:
        case Token::KW_MAIN:
        case Token::KW_FLOAT:
        case Token::KW_IF:
        case Token::KW_ELSE:
            res += "KW";
            break;

            /*case OP*/
        case Token::OP_PLUS:
        case Token::OP_MINUS:
        case Token::OP_MULTIPLY:
        case Token::OP_DIVIDE:
        case Token::OP_PERCENT:
        case Token::OP_EQUAL:
        case Token::OP_GT:
        case Token::OP_LT:
        case Token::OP_ASSIGN:
        case Token::OP_LEQ:
        case Token::OP_GEQ:
        case Token::OP_NEQ:
        case Token::OP_AND:
        case Token::OP_OR:
            res += "OP";
            break;

            /*case SE*/
        case Token::SE_LPARENT:
        case Token::SE_RPARENT:
        case Token::SE_LBRACES:
        case Token::SE_RBARCES:
        case Token::SE_SEMICOLON:
        case Token::SE_COMMA:
            res += "SE";
            break;

            /*IDN*/
        case Token::IDN:
            res += "IDN";
            break;

            /*INT*/
        case Token::INT:
            res += "INT";
            break;

            /*FLOAT*/
        case Token::FLOAT:
            res += "FLOAT";
            break;

            /*UNDEFINED*/
        default:
            res += "UNDEFINED";
            break;
    }

    if (code != Token::IDN && code != Token::INT && code != Token::FLOAT) {
        /*; <SE,24>*/
        res += "," + to_string(code) + ">";
    } else {
        /*10 <INT,10>*/
        res += "," + token + ">";
    }

    cout << res << endl;

    fflush(fp);
    fclose(fp);
    freopen("CON", "w", stdout);

    if (code == Token::UNDEFINED) {
        cout << "UNDEFINED token: " << token << " in line " << lineNum << endl;
    }
}

set<char> getList(char c) {
    set<char> res;
    if (isalpha(c) || c == '_') {
        set<char> list = {'_'};
        //a to z
        for (char x = 'a'; x <= 'z'; ++x) {
            list.insert(x);
        }
        //A to Z
        for (char x = 'A'; x <= 'Z'; ++x) {
            list.insert(x);
        }
        return list;
    } else if (c == '0') {
        return {'0'};
    } else if (c == '.') {
        return {'.'};
    }
        // 1 ~ 9
    else if (c >= '1' && c <= '9') {
        set<char> numList;
        for (char x = '1'; x <= '9'; ++x) {
            numList.insert(x);
        }
        return numList;
    }
    return res;
}


